#ifndef CONFIG_H
#define CONFIG_H

#include <QObject>
#include <QJsonObject>

namespace stitch
{
    class MainConfig;
    class CoreConfig;
    class SessionConfig;

    class Config : public QObject
    {
        Q_OBJECT
    public:
        enum class Source
        {
            Default,
            App,
            User,
            Session
        };

        class Settings
        {
        public:
            Settings() = default;

            Settings(const QJsonObject &p_jobj)
                : m_jobj(p_jobj)
            {
            }

            const QJsonObject &getJson() const;

            void writeToFile(const QString &p_jsonFilePath) const;

            static QSharedPointer<Settings> fromFile(const QString &p_jsonFilePath);

        private:
            QJsonObject m_jobj;
        };

        ~Config();

        static Config &getInst(bool p_isUnitTest = false);

        SessionConfig &getSessionConfig();

        // Used by IConfig.
        QSharedPointer<Settings> getSettings(Source p_src) const;

         QString getConfigFilePath(Source p_src) const;

        CoreConfig &getCoreConfig();

        static const QString c_orgName;

        static const QString c_appName;

        static QString getApplicationVersion();

        static QString getDefaultConfigFilePath();

        static QString getApplicationDirPath();

        static QString getApplicationFilePath();

        QString getAppThemeFolder() const;

        QString getUserThemeFolder() const;

        QString getAppWebStylesFolder() const;

        QString getUserWebStylesFolder() const;

        QString getAppSyntaxHighlightingFolder() const;

        QString getUserSyntaxHighlightingFolder() const;

        void writeSessionSettings(const QJsonObject &p_jobj);

        QString getAppTaskFolder() const;

        QString getUserTaskFolder() const;

    private:
        Config(bool p_isUnitTest, QObject *p_parent = nullptr);

        // Locate the folder path where the config file exists.
        void locateConfigFolder();

        // Name of the core config file.
        static const QString c_configFileName;

        // Name of the session config file.
        static const QString c_sessionFileName;

        static const QString c_userFilesFolder;

        static const QString c_appFilesFolder;

        QScopedPointer<MainConfig> m_config;
        // Absolute path of the app config folder.
        QString m_appConfigFolderPath;

        // Absolute path of the user config folder.
        QString m_userConfigFolderPath;

        // Check if app config exists and is updated.
        // Update it if in need.
        // Return true if there is update.
        bool checkAppConfig();

        void checkUserConfig();

        //
        QScopedPointer<SessionConfig> m_sessionConfig;
    };
}
#endif // CONFIG_H
